<script setup lang="ts">
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'

gsap.registerPlugin(ScrollTrigger)

const canvas = ref<HTMLCanvasElement | null>(null)
const frameCount = 147
const urls = Array.from({ length: frameCount }).fill(0).map((_, i) => `https://www.apple.com/105/media/us/airpods-pro/2019/1299e2f5_9206_4470_b28e_08307a42f19b/anim/sequence/large/01-hero-lightpass/${(i + 1).toString().padStart(4, '0')}.jpg`)

function imageSequence(config: {
  urls: string[]
  canvas: HTMLCanvasElement
  onUpdate?: (index: number, image: HTMLImageElement) => void
  scrollTrigger?: any
}) {
  const { urls, canvas, onUpdate, scrollTrigger } = config
  const ctx = canvas.getContext('2d')

  const playhead = { frame: 0 }
  let curFrame = -1
  let images: HTMLImageElement[]

  const updateImage = () => {
    const frame = Math.round(playhead.frame)
    if (frame !== curFrame) {
      ctx?.clearRect(0, 0, canvas.width, canvas.height)
      ctx?.drawImage(images[frame], 0, 0)
      curFrame = frame
      onUpdate && onUpdate(frame, images[frame])
    }
  }

  images = urls.map((url, i) => {
    const img = new Image()
    img.src = url
    if (i === 0)
      img.onload = updateImage
    return img
  })

  return gsap.to(playhead, {
    frame: images.length - 1,
    ease: 'none',
    onUpdate: updateImage,
    duration: images.length / 30,
    scrollTrigger,
  })
}

onMounted(() => {
  if (canvas.value) {
    imageSequence({
      urls,
      canvas: canvas.value,
      // onUpdate: (index, image) => console.log("drew image index", index, ", image:", image),
      scrollTrigger: {
        start: 0,
        end: 'max',
        scrub: true,
      }
    })
  }
})
</script>

<template>
  <div class="box bg-#000000">
    <canvas ref="canvas" width="1158" height="770"></canvas>
  </div>
</template>

<style lang="scss" scoped>
.box {
  height: 300vh;
}

canvas {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  max-width: 100vw;
  max-height: 100vh;
}
</style>
